package com.longway.common.kit;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

public class ZipKit {
    
    private ZipKit(){
    }
    
    public static void doCompress(String srcFile, String zipFile) throws IOException {
        doCompress(new File(srcFile), new File(zipFile));
    }
    
    /**
     * 文件压缩
     * @param srcFile 目录或者单个文件
     * @param zipFile 压缩后的ZIP文件
     */
    public static void doCompress(File srcFile, File zipFile) throws IOException {
        ZipOutputStream out = null;
        try {
            out = new ZipOutputStream(new FileOutputStream(zipFile));
            doCompress(srcFile, out);
        } catch (Exception e) {
            throw e;
        } finally {
            out.close();//记得关闭资源
        }
    }
    
    public static void doCompress(String filelName, ZipOutputStream out) throws IOException{
        doCompress(new File(filelName), out);
    }
    
    public static void doCompress(File file, ZipOutputStream out) throws IOException{
        doCompress(file, out, "");
    }
    
    public static void doCompress(File inFile, ZipOutputStream out, String dir) throws IOException {
        if ( inFile.isDirectory() ) {
            File[] files = inFile.listFiles();
            if (files!=null && files.length>0) {
                for (File file : files) {
                    String name = inFile.getName();
                    if (!"".equals(dir)) {
                        name = dir + "/" + name;
                    }
                    ZipKit.doCompress(file, out, name);
                }
            }
        } else {
             ZipKit.doZip(inFile, out, dir);
        }
    }
    
    public static void doZip(File inFile, ZipOutputStream out, String dir) throws IOException {
        String entryName = null;
        if (!"".equals(dir)) {
            entryName = dir + "/" + inFile.getName();
        } else {
            entryName = inFile.getName();
        }
        ZipEntry entry = new ZipEntry(entryName);
        out.putNextEntry(entry);
        
        int len = 0 ;
        byte[] buffer = new byte[1024];
        FileInputStream fis = new FileInputStream(inFile);
        while ((len = fis.read(buffer)) > 0) {
            out.write(buffer, 0, len);
            out.flush();
        }
        out.closeEntry();
        fis.close();
    }
    
    /**
	  * 解压文件
	  * 
	  * @param filePath
	  * 压缩文件路径
	  */
	 public static void unzip(String filePath) {
	     File source = new File(filePath);
	    if (source.exists()) {
	       ZipInputStream zis = null;
	         BufferedOutputStream bos = null;
	        try {
	             zis = new ZipInputStream(new FileInputStream(source));
	             ZipEntry entry = null;
	            while ((entry = zis.getNextEntry()) != null
	                     && !entry.isDirectory()) {
	                 File target = new File(source.getParent(), entry.getName());
	                 if (!target.getParentFile().exists()) {
	                     // 创建文件父目录
	                     target.getParentFile().mkdirs();
	                 }
	                 // 写入文件
	                 bos = new BufferedOutputStream(new FileOutputStream(target));
	                 int read = 0;
	                 byte[] buffer = new byte[1024 * 10];
	                 while ((read = zis.read(buffer, 0, buffer.length)) != -1) {
	                     bos.write(buffer, 0, read);
	                 }
	                 bos.flush();
	             }
	             zis.closeEntry();
	         } catch (IOException e) {
	             throw new RuntimeException(e);
	         } finally {
	             IO.closeQuietly(zis, bos);
	         }
	     }
	 }
    /**
     * 文件解压
     * @param zipFile 解压前的ZIP文件
     * @param srcFile 目录或者单个文件
     */
    @SuppressWarnings("unchecked")
	public static void doUnCompress(String zipFile, String srcFile) {  
        FileOutputStream fileOut;  
        File file;  
        InputStream inputStream;  
        byte[]   buf = new byte[1024*4];  
        try {  
            //生成一个zip的文件  
        	file = new File(zipFile);
            ZipFile   zipfile = new ZipFile(zipFile);  
            //遍历zipFile中所有的实体，并把他们解压出来  
            for (Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zipfile.entries(); 
            entries.hasMoreElements();) {  
            	ZipEntry entry = (ZipEntry) entries.nextElement();
                //生成他们解压后的一个文件    
                file = new File(srcFile+File.separator+entry.getName());  
                if (entry.isDirectory()) {  
                    file.mkdirs();  
                } else {  
                    // 如果指定文件的目录不存在,则创建之.  
                    File parent = file.getParentFile();  
                    if (!parent.exists()) {  
                        parent.mkdirs();  
                    }    
                    //获取出该压缩实体的输入流   
                    inputStream = zipfile.getInputStream(entry);  
                    fileOut = new FileOutputStream(file);  
                    int length = 0;  
                    //将实体写到本地文件中去  
                    while ((length = inputStream.read(buf)) > 0) {  
                        fileOut.write(buf, 0, length);  
                    }  
                    fileOut.close();  
                    inputStream.close();  
                }  
            }  
            zipfile.close();  
            //解压完后将原压缩文件删除  
            File dataZipfile = new File(zipFile);  
            if(dataZipfile.exists()){  
            	dataZipfile.delete();  
            }     
        } catch (IOException ioe) {  
            ioe.printStackTrace();  
        }  
    }  
    
    public static void main(String[] args) throws IOException {
        doCompress("D:/shop/upload", "D:/upload.zip");
    }
}
